﻿package org.dm.math.geom
{
	/**
	 * ...
	 * @author Scott
	 */
	public class Num2
	{
		public static const RADTODEG:Number = 180 / Math.PI;
		public static const DEGTORAD:Number = Math.PI / 180;
		
		public var x:Number;
		public var y:Number;
		
		public function Num2(x:Number = 0, y:Number = 0) 
		{
			this.x = x;
			this.y = y;
		}
		
		public function toString():String
		{
			return "[" + Math.round (this.x * 100) / 100; + ", " + Math.round (this.y * 100) / 100; + "]";
		}
		
		public function clone():Num2
		{
			return new Num2(this.x, this.y);
		}
		
		public function copyTo(v:Num2):void
		{
			v.x = this.x;
			v.y = this.y;
		}
		public function copyFrom(v:Num2):void
		{
			this.x = v.x;
			this.y = v.y;
		}	
		
		public function get modulo():Number 
		{
			return Math.sqrt((x*x)+(y*y));
		}
		
		public function normalise():void 
		{
			var m:Number = this.modulo;
			if (m != 0 && m != 1)
			{
				this.x = this.x/m;
				this.y = this.y/m;
			}			
		}
		
		public function reverse():void 
		{
			this.x = -this.x;
			this.y = -this.y;
		}
		
		public static function add(v:Num2, w:Num2):Num2
		{
			return new Num2(v.x += w.x, v.y + w.y);
		}
		
		public static function subtract(v:Num2, w:Num2):Num2
		{
			return new Num2( v.x - w.x, v.y - w.y);
		}
		
		public function plusEq(v:Num2):void
		{
			x += v.x;
			y += v.y;
			
		}
		public function minusEq(v:Num2):void
		{
			x -= v.x;
			y -= v.y; 
			
		}
		
		public function divideEq(d:Number):void
		{
			if (d != 0)
			{
				x /= d; 
				y /= d; 
			}
		}
		
		public function multiplyEq(d:Number):void
		{
			x*=d; 
			y*=d; 
		}
		
		
		public static function multiplyScalar(v:Num2, n:Number):Num2
		{
			return new Num2
			(
				v.x*n,
				v.y*n
			);			
		}
		
		public static function dot(v:Num2, w:Num2):Number
		{
			return v.x * w.x + v.y * w.y ;
		}		
		
		public function angle():Number
		{
			return Math.atan2(y,x);
		}
	
		public function rotate(angle:Number):void
		{
			var cosRY:Number = Math.cos(angle);
			var sinRY:Number = Math.sin(angle);
			var temp:Num2 = clone();
			
			this.x = temp.x * cosRY - temp.y * sinRY;
			this.y = temp.x * sinRY + temp.y * cosRY;			
		}
		
		public function reset(x:Number = 0, y:Number = 0):void
		{
			this.x = x;
			this.y = y;
		}
		 
		public function isModuloLessThan(v:Number):Boolean
		{
			return (moduloSquared<(v*v)); 
		}
		
		public function isModuloGreaterThan(v:Number):Boolean
		{
			return (moduloSquared>(v*v)); 
		}
		
		public function isModuloEqualTo(v:Number):Boolean
		{
			return (moduloSquared==(v*v)); 
		}
			
		public function get moduloSquared():Number
		{
			return ( this.x * this.x + this.y * this.y );
		}
		
		public static function distance(v1:Num2, v2:Num2):Number
		{
			return Math.sqrt((v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y - v2.y));
		}
		
		public static function distanceEq(v1:Num2, v2:Num2):Number
		{
			return (v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y - v2.y);
		}
	}

}